﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace libC.semantic
{
    public class semanticAnalyzer
    {

        /// <summary>
        /// 定义 Extern C
        /// </summary>
        public Dictionary<string, bool> defExternCDic = new Dictionary<string, bool>();

        private semanticAST _root = null;
        private uint lastAstId = 0;
        /// <summary>
        /// {ID ,ast} 的字典
        /// </summary>
        private Dictionary<uint, semanticAST> astDic = new Dictionary<uint, semanticAST>();
        /// <summary>
        ///  {ast标记字符串 ,ID} 的字典
        /// </summary>
        private Dictionary<string, uint> filePathIdDic = new Dictionary<string, uint>();
        private Dictionary<string, stNode> stNodeDic;
        /// <summary>
        /// root ast节点
        /// </summary>
        public semanticAST root => _root;
        /// <summary>
        /// ast 的数量
        /// </summary>
        public int astCount => astDic.Count;

        /// <summary>
        /// 构造 语义分析器
        /// </summary>
        /// <param name="nodeDic">语法树根节点 字典[文件路径 : 节点]</param>
        public semanticAnalyzer(Dictionary<string, stNode> nodeDic)
        {
            stNodeDic = nodeDic;
            //ast标记字符串 记录到 字典 
            foreach (var item in nodeDic)
            {
                semanticAST sAst = newAst(item.Value);
                var currID = lastAstId;
                filePathIdDic[item.Key] = currID;
            }

            //
        }
        /// <summary>
        /// 获取 语义抽象语法树
        /// </summary>
        /// <param name="astID">树ID</param>
        /// <returns></returns>
        public semanticAST getSemantAst(uint astID)
        {
            semanticAST result;
            astDic.TryGetValue(astID, out result);
            return result;
        }
        /// <summary>
        /// 获取 语义抽象语法树
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns></returns>
        public semanticAST getSemantAst(string filePath)
        {
            if (!filePathIdDic.ContainsKey(filePath)) return null;
            uint astID = filePathIdDic[filePath];
            semanticAST result;
            astDic.TryGetValue(astID, out result);
            return result;
        }

        /// <summary>
        /// 计算 获得含语义AST
        /// </summary>
        public static semanticAST CalcSemanticAST(stNode rootNode)
        {
            var sAst = new semanticAST(rootNode);
            sAst.parse();
            //print tree
            sAst.printTree();
            return sAst;
        }

        /// <summary>
        /// 解析
        /// </summary>
        public void parse()
        {
            //遍历处理各 tree
            foreach (var item in astDic)
            {
                var astID = item.Key;
                var semAst = item.Value;
                if (_root == null)
                {
                    _root = semAst;
                }
                semAst.parse();

                //汇聚 extern "C" 的定义
                int defCount = semAst.defExternCDic.Count;
                if (defCount > 0)
                {
                    foreach (var item_1 in semAst.defExternCDic)
                    {
                        defExternCDic[item_1.Key] = true;
                    }
                }
            }

            //set root
        }

        /// <summary>
        /// 获取一个 semanticAST
        /// </summary>
        /// <param name="rootNode"></param>
        /// <returns></returns>
        private semanticAST newAst(stNode rootNode)
        {
            semanticAST result = new semanticAST(rootNode);
            astDic[lastAstId++] = result;
            return result;
        }
    }
}
